home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 113_01 / a15eval.c < prev    next >
Text File  |  1985-03-09  |  6KB  |  216 lines

  1. /*
  2.     HEADER:        CUG113;
  3.     TITLE:        1802 Cross-Assembler (BDS C Version);
  4.     FILENAME:    A15EVAL.C;
  5.     VERSION:    1.2;
  6.     DATE:        07/22/1985;
  7.  
  8.     DESCRIPTION:    "This program lets you use your CP/M-80-based computer
  9.             to assemble code for the RCA 1802, 1804, 1805, 1805A,
  10.             1806, AND 1806A microprocessors.  The program is
  11.             written in BDS C for the best possible performance on
  12.             8-bit machines.  All assembler features are supported
  13.             except relocation, linkage, listing control, and
  14.             macros.";
  15.  
  16.     KEYWORDS:    Software Development, Assemblers, Cross-Assemblers,
  17.             RCA, CDP1802, CDP1805A;
  18.  
  19.     SEE-ALSO:    CUG149, 1805A Cross-Assembler (Portable);
  20.  
  21.     SYSTEM:        CP/M-80;
  22.     COMPILERS:    BDS C;
  23.  
  24.     WARNINGS:    "This package is specifically tailored to CP/M-80
  25.             machines and the rather non-standard, but high-
  26.             performance BDS C compiler.  For other environments,
  27.             use the portable version of this package on CUG149.";
  28.  
  29.     AUTHORS:    William C. Colley III;
  30. */
  31.  
  32. /*
  33.     1805A Cross-Assembler  v 1.2
  34.  
  35.     Copyright (c) 1980, 82, 83, 85 William C. Colley, III.
  36.  
  37.     July 1982 -- Adapted from my 1802 cross-assembler.  WCC3.
  38.  
  39.     Vers 1.0 -- March 1983 -- Added 1805A opcodes to the 1805 set.  WCC3.
  40.  
  41.     Vers 1.1 -- March 1983 -- Added CPU pseudo-op to combine 1802 and 1805A
  42.             cross-assemblers into a single program.  WCC3.
  43.  
  44.     Vers 1.2 -- June 1985 -- Fixed IF block nesting mechanism bug and bug
  45.             in 1805A SCAL opcode.  WCC3.
  46.  
  47. File:    a15eval.c
  48.  
  49. Routines to crunch on source text chunks and give back
  50. evaluated expressions, opcode parameters, etc.
  51. */
  52.  
  53. /*  Get Globals:  */
  54.  
  55. #include "a15.h"
  56.  
  57. /*
  58. Function to evaluate the next expression on the present source line.
  59. Function returns the value of the expression.  In addition, a global
  60. flag, evalerr, is set to TRUE if an error occurred anywhere in the
  61. evaluation process.  The precidence parameter, prec, is for the benefit
  62. of the recursion.  In the first call to the routine, use START.
  63. */
  64.  
  65. eval(prec)
  66. char prec;
  67. {
  68.     unsigned valu1, valu2;
  69.     char getitem(), c;
  70.  
  71.     for (;;) {
  72.     switch (getitem(&valu1,SMALST)) {
  73.         case COMMA:      if (prec != START) backitem(0,COMMA);
  74.               goto enderr;
  75.  
  76.         case END_LIN: backitem(0,END_LIN);
  77.         enderr:       evalerr = TRUE;  markerr('E');  return 0;
  78.  
  79.         case OPERATR: if (valu1 == NOT) valu1 = ~eval(UOP2);
  80.               else if (valu1 == '-') valu1 = -eval(UOP1);
  81.               else if (valu1 == '+') valu1 = eval(UOP1);
  82.               else if (valu1 == '(') valu1 = eval(LPREN);
  83.               else if (valu1 == HIGH) valu1 = eval(UOP3) >> 8;
  84.               else if (valu1 == LOW) valu1 = eval(UOP3) & 0xff;
  85.               else { evalerr = TRUE;  markerr('E');  break; }
  86.  
  87.         case VALUE:   for (;;) {
  88.                   switch (getitem(&valu2,SMALST)) {
  89.                   case COMMA:   if (prec != START)
  90.                             backitem(0,COMMA);
  91.                         goto endeval;
  92.  
  93.                   case END_LIN: backitem(0,END_LIN);
  94.                   endeval:      if (prec == LPREN) {
  95.                             evalerr = TRUE;
  96.                             markerr('(');
  97.                         }
  98.                         return (evalerr) ? 0 : valu1;
  99.  
  100.                   case VALUE:   evalerr = TRUE;  markerr('E');
  101.                         break;
  102.  
  103.                   case OPERATR: if (valu2 == '(' ||
  104.                             valu2 == NOT ||
  105.                             valu2 == HIGH ||
  106.                             valu2 == LOW) {
  107.                             evalerr = TRUE;
  108.                             markerr('E');  break;
  109.                         }
  110.                         if (prec <= getprec(valu2)) {
  111.                             backitem(valu2,OPERATR);
  112.                             return valu1;
  113.                         }
  114.                         switch (c = valu2) {
  115.                             case '+':   valu1 += eval(ADDIT); break;
  116.  
  117.                             case '-':   valu1 -= eval(ADDIT); break;
  118.  
  119.                             case '*':   valu1 *= eval(MULT); break;
  120.  
  121.                             case '/':   valu1 /= eval(MULT); break;
  122.  
  123.                             case MOD:   valu1 %= eval(MULT); break;
  124.  
  125.                             case AND:    valu1 &= eval(LOG1); break;
  126.  
  127.                             case OR:    valu1 |= eval(LOG2); break;
  128.  
  129.                             case XOR:   valu1 ^= eval(LOG2); break;
  130.  
  131.                             case '>':   valu1 = (valu1 > eval(RELAT)) ? 0xffff : 0; break;
  132.  
  133.                             case GRTEQ: valu1 = (valu1 >= eval(RELAT)) ? 0xffff : 0; break;
  134.  
  135.                             case '=':   valu1 = (valu1 == eval(RELAT)) ? 0xffff : 0; break;
  136.  
  137.                             case NOTEQ: valu1 = (valu1 != eval(RELAT)) ? 0xffff : 0; break;
  138.  
  139.                             case '<':   valu1 = (valu1 < eval(RELAT)) ? 0xffff : 0; break;
  140.  
  141.                             case LESEQ: valu1 = (valu1 <= eval(RELAT)) ? 0xffff : 0; break;
  142.  
  143.                             case SHL:   if ((valu2 = eval(MULT)) > 15) {
  144.                                     evalerr = TRUE;
  145.                                     markerr('E');  break;
  146.                                 }
  147.                                 valu1 <<= valu2;  break;
  148.  
  149.                             case SHR:   if ((valu2 = eval(MULT)) > 15) {
  150.                                     evalerr = TRUE;
  151.                                     markerr('E');  break;
  152.                                 }
  153.                                 valu1 >>= valu2;  break;
  154.  
  155.                             case ')':   if (prec == LPREN) return valu1;
  156.                                 else {
  157.                                     evalerr = TRUE;
  158.                                     markerr('(');  break;
  159.                                 }
  160.                         }
  161.                   }
  162.               }
  163.     }
  164.     }
  165. }
  166.  
  167. /*
  168. Function to get the precedence of a binary operator.
  169. Function returns the precedence value.
  170. */
  171.  
  172. getprec(operator)
  173. char operator;
  174. {
  175.     switch (operator) {
  176.     case '*':
  177.     case '/':
  178.     case MOD:
  179.     case SHL:
  180.     case SHR:    return MULT;
  181.  
  182.     case '+':
  183.     case '-':    return ADDIT;
  184.  
  185.     case '>':
  186.     case '=':
  187.     case '<':
  188.     case GRTEQ:
  189.     case NOTEQ:
  190.     case LESEQ:  return RELAT;
  191.  
  192.     case AND:    return LOG1;
  193.  
  194.     case OR:
  195.     case XOR:    return LOG2;
  196.  
  197.     case HIGH:
  198.     case LOW:    return UOP3;
  199.  
  200.     case ')':    return RPREN;
  201.     }
  202. }
  203.  
  204. /*
  205. Function to mark up an error in the line if one isn't already marked up.  The
  206. error code letter comes in through letter.
  207. */
  208.  
  209. markerr(letter)
  210. char letter;
  211. {
  212.     if (errcode == ' ') { errcode = letter;  errcount++; }
  213. }
  214. ('E');  break;
  215.                                 }
  216.                                 valu1 >>= valu2;  brea